package io.sundial.job;

import java.util.Map;

/**
 * 作业接口
 * 作业对象的顶级接口，其下面会有更多子接口，该接口仅仅描述一个类是一个作业类，并且包含最基本的执行方法{@link Job#run(JobContext)}。
 * 框架在进行作业调度执行时最核心的调用就是{@link Job#run(JobContext)}方法的调用，也就是说一个作业的最核心逻辑应该在{@link Job#run(JobContext)}方法中实现。
 * 享受框架更丰富的特性需要使用其子接口或抽象类。
 * 作业实现只是包含了作业的基本业务逻辑，并不包括何时执行以及以何种参数执行。
 *
 * @author Payne 646742615@qq.com
 * 2018/12/6 10:23
 */
public interface Job {

    /**
     * 获取作业名称
     * 作业分组 + 作业名称作为作业的唯一标识，如果存在同组同名的作业，则最先搜索到的作业会被使用而后面的作业会被忽略。
     *
     * @return 作业名称
     */
    String name();

    /**
     * 获取作业分组
     * 作业分组 + 作业名称作为作业的唯一标识，如果存在同组同名的作业，则最先搜索到的作业会被使用而后面的作业会被忽略。
     *
     * @return 作业分组
     */
    String group();

    /**
     * 获取作业类型
     * 作业类型是作业的实现方式，例如Java / Shell ...
     *
     * @return 作业类型
     */
    String type();

    /**
     * 获取作业版本
     *
     * @return 作业版本
     */
    String version();

    /**
     * 获取最大分片数量
     * n < 0：无限制最大分片数量
     * 0 - 1：不支持分片，即只支持单个执行。
     * n > 1: 最大支持n个分片
     *
     * @return 最大分片数量
     */
    int shardable();

    /**
     * 获取作业的形式参数列表
     *
     * @return 作业的形式参数列表
     */
    Map<String, JobParameter> parameters();

    /**
     * 获取作业的详细描述
     *
     * @return 作业的详细描述
     */
    String description();

    /**
     * 作业执行方法
     * 一个作业的核心逻辑方法，作业实现类需要保证方法返回时所有作业执行任务均已完成，包括开启的子线程也执行结束。
     * 也就是说框架在该方法的调用返回值之时认为任务已经全部执行完成，所有资源可以回收用以下次或别的作业调度。
     *
     * @param jobContext 作业执行上下文
     * @return 作业执行结果
     * @throws JobException 作业执行异常
     */
    JobResult run(JobContext jobContext) throws JobException;

}
